package top.hserver.gateway.core.node;

import top.hserver.core.ioc.annotation.Bean;
import top.hserver.core.ioc.annotation.Track;
import top.hserver.gateway.core.bean.RouterInfo;
import top.hserver.gateway.core.strategy.ServerNode;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 节点管理器
 *
 * @author hxm
 */

@Bean
public class ServerNodeManager implements Manager {

    /**
     * 路由ID，节点ID，服务节点集群
     */
    private static final Map<String, Map<String, ServerNode>> serverNodeMap = new ConcurrentHashMap<>();
    private static final Map<String, RouterInfo> serverRouter = new ConcurrentHashMap<>();

    @Override
    public List<ServerNode> getAllServerNode() {
        List<ServerNode> nodes = new ArrayList<>();
        serverNodeMap.forEach((k, v) -> {
            v.forEach((k1, v1) -> {
                nodes.add(v1);
            });
        });
        return nodes;
    }

    @Override
    public Boolean markUnhealthy(String routerId, String nodeId) {
        serverNodeMap.get(routerId).get(nodeId).setHealth(false);
        return true;
    }

    @Override
    public void addServerNode(String routerId, ServerNode serverNodes) {
        Map<String, ServerNode> nodeMap = serverNodeMap.get(routerId);
        if (nodeMap == null) {
            nodeMap = new ConcurrentHashMap<>();
        }
        nodeMap.put(serverNodes.getNodeId(), serverNodes);
        serverNodeMap.put(routerId, nodeMap);
        serverRouter.put(serverNodes.getUrl(), new RouterInfo(serverNodes.getRouterId(),serverNodes.getStrategyType()));
    }


    @Override
    public synchronized void addConnect(String routerId, String nodeId) {
        ServerNode serverNode = serverNodeMap.get(routerId).get(nodeId);
        serverNode.setConnectNum(serverNode.getConnectNum()+1);
    }

    @Override
    public List<ServerNode> getHealthy(String routerId) {
        //节点存在上线和备用，当全部线上节点挂逼后启用备用服务

        //获取线上的
        List<ServerNode> collect = serverNodeMap.get(routerId).values().stream()
                .filter(x -> x.getHealth() != null && x.getHealth() && !x.getType())
                .collect(Collectors.toList());
        if (collect.size()>0){
            return collect;
        }

        //线上挂逼了，就获取备用的
       collect = serverNodeMap.get(routerId).values().stream()
                .filter(x -> x.getHealth() != null && x.getHealth() && x.getType())
                .collect(Collectors.toList());
        return collect;
    }


    @Override
    public RouterInfo getRouterIdByUrl(String url) {
        Optional<Map.Entry<String, RouterInfo>> first = serverRouter.entrySet().stream().filter(e -> {
            if (url.indexOf(e.getKey()) == 0) {
                return true;
            }
            return false;
        }).findFirst();
        return first.get().getValue();
    }


    @Override
    public void clearAll() {
        serverNodeMap.clear();
        serverRouter.clear();
    }
}
